package com.wongoing.apiclient.alipay;

import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.wongoing.apiclient.alipay.query.Alipay;
import com.wongoing.apiclient.weixin.WXPayUtil;

public class AlipayHelper {

			//支付类型
			private final static String payment_type = "1";
			private final static String service = "yeefeipass_create_order";
			//必填，不能修改
			//服务器异步通知页面路径
			//private static String notify_url = "http://localhost:8080/create_direct_pay_by_user-JAVA-UTF-8/notify_url.jsp";
			//需http://格式的完整路径，不能加?id=123这类自定义参数

			//页面跳转同步通知页面路径
			//private static String return_url = "http://localhost:8080/create_direct_pay_by_user-JAVA-UTF-8/return_url.jsp";
			//需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/

			//////////////////////////////////////////////////////////////////////////////////
			/**
			 * 功能说明：阿里银联支付方式调用
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午1:08:52
			 * @param WIDout_trade_no 商户订单号
			 * @param WIDtotal_amount 支付金额
			 * @param WIDsubject 订单标题
			 * @param WIDbody 订单描述
			 * @param WIDdefaultbank 默认银行
			 * @param ip IP地址
			 * @param WIDShowUrl 商品显示URL
			 * @param notify_url 同步通知地址 
			 * @param resturnUrl 异步通知地址
			 * @return
			 * @throws AlipayApiException
			 * @throws MalformedURLException
			 * @throws DocumentException
			 * @throws IOException
			 */
			public static String payWithBank(String WIDout_trade_no, String WIDtotal_amount, String WIDsubject, String WIDbody,String WIDdefaultbank,
					String ip, String  WIDShowUrl, String resturnUrl) throws Exception, IOException {

				//页面跳转同步通知页面路径
				String return_url = resturnUrl;
				//商户订单号
				String out_trade_no = new String(WIDout_trade_no.getBytes("ISO-8859-1"),"UTF-8");
				//商户网站订单系统中唯一订单号，必填

				//订单名称
				String subject = new String(WIDsubject.getBytes("ISO-8859-1"),"UTF-8");
				//必填

				//付款金额
				String total_fee = new String(WIDtotal_amount.getBytes("ISO-8859-1"),"UTF-8");
				//必填

				//订单描述

				String body = new String(WIDbody.getBytes("ISO-8859-1"),"UTF-8");
				//默认支付方式
				String paymethod = "bankPay";
				//必填
				//默认网银
				String defaultbank = new String(WIDdefaultbank.getBytes("ISO-8859-1"),"UTF-8");
				//必填，银行简码请参考接口技术文档

				//商品展示地址
				String show_url = new String(WIDShowUrl.getBytes("ISO-8859-1"),"UTF-8");
				//需以http://开头的完整路径，例如：http://www.商户网址.com/myorder.html

				//防钓鱼时间戳
				String anti_phishing_key =  AlipaySubmit.query_timestamp();
				//若要使用请调用类文件submit中的query_timestamp函数

				//客户端的IP地址
				String exter_invoke_ip = ip;
				//非局域网的外网IP地址，如：221.0.0.1
				
				
				//////////////////////////////////////////////////////////////////////////////////
				
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "create_direct_pay_by_user");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("seller_email", AlipayConfig.seller_email);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("payment_type", payment_type);
				sParaTemp.put("notify_url", AlipayConfig.notify_url);
				sParaTemp.put("return_url", return_url);
				sParaTemp.put("out_trade_no", out_trade_no);
				sParaTemp.put("subject", subject);
				sParaTemp.put("total_fee", total_fee);
				sParaTemp.put("body", body);
				sParaTemp.put("paymethod", paymethod);
				sParaTemp.put("defaultbank", defaultbank);
				sParaTemp.put("show_url", show_url);
				sParaTemp.put("anti_phishing_key", anti_phishing_key);
				sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
				
				//建立请求
				//String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,"post","确认");
				//建立请求
				String url = AlipaySubmit.buildRequest(sParaTemp);
				url = url.replace("#", "%23");
				// 输出
				return url;
				
				//				//商户订单号,商户网站订单系统中唯一订单号，必填
//				String out_trade_no = new String(WIDout_trade_no.getBytes("ISO-8859-1"),"UTF-8");;
//				//订单名称，必填
//				String subject = WIDsubject;
//				//付款金额,必填
//				String total_fee = WIDtotal_amount;
//				//订单描述
//				String body = WIDbody;
//				//默认支付方式
//				String paymethod = "bankPay";
//				//必填
//				//默认网银
//				String defaultbank = WIDdefaultbank;
//				//必填，银行简码请参考接口技术文档
//				//商品展示地址,需以http://开头的完整路径，例如：http://www.商户网址.com/myorder.html
//				String show_url = WIDShowUrl;
//				//防钓鱼时间戳
//				String anti_phishing_key = AlipaySubmit.query_timestamp();
//				//若要使用请调用类文件submit中的query_timestamp函数
//				//客户端的IP地址
//				String exter_invoke_ip = ip;
//				//非局域网的外网IP地址，如：221.0.0.1
//				//把请求参数打包成数组
//				Map<String, String> sParaTemp = new HashMap<String, String>();
//				sParaTemp.put("service", service);
//		        sParaTemp.put("partner", AlipayConfig.partner);
//		        sParaTemp.put("seller_email", AlipayConfig.seller_email);
//		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
//				sParaTemp.put("payment_type", payment_type);
//				sParaTemp.put("notify_url", notify_url);
//				sParaTemp.put("return_url", resturnUrl);
//				sParaTemp.put("out_trade_no", out_trade_no);
//				sParaTemp.put("subject", subject);
//				sParaTemp.put("total_fee", total_fee);
//				sParaTemp.put("body", body);
//				sParaTemp.put("paymethod", paymethod);
//				sParaTemp.put("defaultbank", defaultbank);
//				sParaTemp.put("show_url", show_url);
//				sParaTemp.put("anti_phishing_key", anti_phishing_key);
//				sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
//				//建立请求
//				String result = AlipaySubmit.buildRequest(sParaTemp,"get","确认");
			
			}
	
			/**
			 * 功能说明：扫码支付（即时到账）
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午3:25:37
			 * @param WIDout_trade_no  商户订单号
			 * @param WIDtotal_amount 总金额
			 * @param WIDsubject 订单标题
			 * @param WIDbody  订单描述
			 * @param resturnUrl 通不通知
			 * @param ip ip
			 * @param WIDShowUrl 商品显示URL
			 * @return
			 * @throws MalformedURLException
			 * @throws DocumentException
			 * @throws IOException
			 * @throws JAXBException 
			 */
			public static String payResult(String WIDout_trade_no, String WIDtotal_amount, String WIDsubject, String WIDbody,
					  String resturnUrl, String ip, String  WIDShowUrl) throws IOException, JAXBException {
				String anti_phishing_key = AlipaySubmit.query_timestamp();
				//若要使用请调用类文件submit中的query_timestamp函数
				//客户端的IP地址
				String exter_invoke_ip = ip;
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "create_direct_pay_by_user");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("seller_email", AlipayConfig.seller_email);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("payment_type", payment_type);
				sParaTemp.put("notify_url", AlipayConfig.notify_url);
				sParaTemp.put("return_url", resturnUrl);
				sParaTemp.put("out_trade_no", WIDout_trade_no);
				sParaTemp.put("subject", WIDsubject);
				sParaTemp.put("total_fee", WIDtotal_amount);
				sParaTemp.put("body", WIDbody);
				sParaTemp.put("show_url", WIDShowUrl);
				sParaTemp.put("anti_phishing_key", anti_phishing_key);
				sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
				sParaTemp.put("it_b_pay", "10m");
				//建立请求
				String url = AlipaySubmit.buildRequest(sParaTemp);
				url = url.replace("#", "%23");
				return url;
			
			} 
			
			/**
			 * 功能说明：扫码支付（即时到账）
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午3:25:37
			 * @param WIDout_trade_no  商户订单号
			 * @param WIDtotal_amount 总金额
			 * @param WIDsubject 订单标题
			 * @param WIDbody  订单描述
			 * @param notify_url 异步通知
			 * @param resturnUrl 通不通知
			 * @param ip ip
			 * @param WIDShowUrl 商品显示URL
			 * @return
			 * @throws MalformedURLException
			 * @throws DocumentException
			 * @throws IOException
			 * @throws JAXBException 
			 */
			public static String payResult(String WIDout_trade_no, String WIDtotal_amount, String WIDsubject, String WIDbody,
					 String notify_url, String resturnUrl, String ip, String  WIDShowUrl) throws IOException, JAXBException {
				String anti_phishing_key = AlipaySubmit.query_timestamp();
				//若要使用请调用类文件submit中的query_timestamp函数
				//客户端的IP地址
				String exter_invoke_ip = ip;
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "create_direct_pay_by_user");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("seller_email", AlipayConfig.seller_email);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("payment_type", payment_type);
				sParaTemp.put("notify_url", notify_url);
				sParaTemp.put("return_url", resturnUrl);
				sParaTemp.put("out_trade_no", WIDout_trade_no);
				sParaTemp.put("subject", WIDsubject);
				sParaTemp.put("total_fee", WIDtotal_amount);
				sParaTemp.put("body", WIDbody);
				sParaTemp.put("show_url", WIDShowUrl);
				sParaTemp.put("anti_phishing_key", anti_phishing_key);
				sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
				sParaTemp.put("it_b_pay", "10m");
				//建立请求
				String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,"get","确认");
				return sHtmlText;
			} 
			
			/**
			 * 功能说明：扫码支付是否成功的判断函数
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午3:31:40
			 * @param requestParams
			 * @return
			 * @throws Exception
			 */
			public static boolean payResultInfo(Map<String, String[]> requestParams) throws Exception {
				//获取支付宝GET过来反馈信息
				Map<String,String> params = new HashMap<String,String>();
				for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
					String name = (String) iter.next();
					String[] values = (String[]) requestParams.get(name);
					String valueStr = "";
					for (int i = 0; i < values.length; i++) {
						valueStr = (i == values.length - 1) ? valueStr + values[i]
								: valueStr + values[i] + ",";
					}
					
					System.out.println("支付宝验证部分测试未解码valueStr："+valueStr);
					//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//					valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
					System.out.println("支付宝验证部分测试已解码valueStr："+valueStr);
					params.put(name, valueStr);
				}
				//计算得出通知验证结果
				return AlipayNotify.verify(params);
			}
			
			/**
			 * 功能说明：即时到账退款接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午5:44:14
			 * @param WIDbatch_no 退款批次号
			 * @param WIDrefund_date 退款请求时间
			 * @param WIDbatch_num 退款总笔数
			 * @param WIDdetail_data 单笔数据集
			 * @param notify_url 异步通知地址
			 * @return
			 * @throws Exception
			 */
			public static String payRefund(String WIDbatch_no,String WIDrefund_date,String WIDbatch_num,String WIDdetail_data,String notify_url) throws Exception {
				//需http://格式的完整路径，不允许加?id=123这类自定义参数
				//退款批次号
				String batch_no = WIDbatch_no; //必填，每进行一次即时到账批量退款，都需要提供一个批次号，必须保证唯一性
				//退款请求时间
				String refund_date = WIDrefund_date;//必填，格式为：yyyy-MM-dd hh:mm:ss
				//退款总笔数
				String batch_num = WIDbatch_num;//必填，即参数detail_data的值中，“#”字符出现的数量加1，最大支持1000笔（即“#”字符出现的最大数量999个）
				//单笔数据集
				String detail_data = WIDdetail_data;//必填，格式详见“4.3 单笔数据集参数说明”
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "refund_fastpay_by_platform_nopwd");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("notify_url", notify_url);
				sParaTemp.put("batch_no", batch_no);
				sParaTemp.put("refund_date", refund_date);
				sParaTemp.put("batch_num", batch_num);
				sParaTemp.put("detail_data", detail_data);
				//建立请求
				String sHtmlText = AlipaySubmit.buildRequest("", "", sParaTemp);
				return sHtmlText;
			}
			
			/**
			 * 功能说明：即时到账退款接口
			 * 修改说明：返回Map<String,Object>
			 * @author 吴兆强
			 * @date 2017年12月28日 下午5:44:14
			 * @param WIDbatch_no 退款批次号    退款号格式：8位时间+3位流水
			 * @param WIDrefund_date 退款请求时间    时间格式：yyyy-MM-dd HH:ss:mm
			 * @param WIDbatch_num 退款总笔数
			 * @param WIDdetail_data 单笔数据集     数据拼接方式：支付宝交易号^退款金额^退款理由
			 * @param notify_url 异步通知地址
			 * @return
			 * @throws Exception
			 */
			public static Map<String, String> payRefundToMap(String WIDbatch_no,String WIDrefund_date,String WIDbatch_num,String WIDdetail_data,String notify_url) throws Exception {
				//需http://格式的完整路径，不允许加?id=123这类自定义参数
				//退款批次号
				String batch_no = WIDbatch_no; //必填，每进行一次即时到账批量退款，都需要提供一个批次号，必须保证唯一性
				//退款请求时间
				String refund_date = WIDrefund_date;//必填，格式为：yyyy-MM-dd hh:mm:ss
				//退款总笔数
				String batch_num = WIDbatch_num;//必填，即参数detail_data的值中，“#”字符出现的数量加1，最大支持1000笔（即“#”字符出现的最大数量999个）
				//单笔数据集
				String detail_data = WIDdetail_data;//必填，格式详见“4.3 单笔数据集参数说明”
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "refund_fastpay_by_platform_nopwd");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("notify_url", notify_url);
				sParaTemp.put("batch_no", batch_no);
				sParaTemp.put("refund_date", refund_date);
				sParaTemp.put("batch_num", batch_num);
				sParaTemp.put("detail_data", detail_data);
				//建立请求
				String sHtmlText = AlipaySubmit.buildRequest("", "", sParaTemp);
				return WXPayUtil.xmlToMap(sHtmlText);
			}
			/**
			 * 功能说明：支付宝订单查询接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午5:48:20
			 * @param WIDtrade_no 支付宝交易号
			 * @param WIDout_trade_no 商户订单号
			 * @return
			 * @throws Exception 
			 */
			public static String payQuery(String WIDtrade_no, String WIDout_trade_no) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "single_trade_query");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("trade_no", WIDtrade_no);
				sParaTemp.put("out_trade_no", WIDout_trade_no);
				//建立请求
				return AlipaySubmit.buildRequest("", "", sParaTemp);
			}
			
			/**
			 * 功能说明：支付宝支付订单查询接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月29日 下午3:26:04
			 * @param WIDtrade_no
			 * @param WIDout_trade_no
			 * @return
			 * @throws Exception
			 */
			public static Map<String,String> payQueryToMap(String WIDtrade_no, String WIDout_trade_no) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "single_trade_query");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("trade_no", WIDtrade_no);
				sParaTemp.put("out_trade_no", WIDout_trade_no);
				//建立请求
				return WXPayUtil.xmlToMap(AlipaySubmit.buildRequest("", "", sParaTemp));
			}
			
			/**
			 * 功能说明：订单查询
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月29日 下午3:59:05
			 * @param WIDtrade_no
			 * @param WIDout_trade_no
			 * @return
			 * @throws Exception
			 */
		
			public static Alipay payQueryToBean(String WIDtrade_no, String WIDout_trade_no) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "single_trade_query");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
		        if(WIDtrade_no!=null)
		        	sParaTemp.put("trade_no", WIDtrade_no);
		        if(WIDout_trade_no!=null)
		        	sParaTemp.put("out_trade_no", WIDout_trade_no);
				//建立请求
				String resultStr = AlipaySubmit.buildRequest("", "", sParaTemp);
				System.out.println(resultStr);
				JAXBContext context = JAXBContext.newInstance(Alipay.class);  
		        Unmarshaller unmarshaller = context.createUnmarshaller();  
		        Alipay results = (Alipay)unmarshaller.unmarshal(new StringReader(resultStr));
				return results;
			}
			/**
			 * 功能说明：支付宝退款查询接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午5:54:38
			 * @param WIDbatch_no 批量退款批次号
			 * @param WIDtrade_no 支付宝交易号
			 * @return
			 * @throws Exception 
			 */
			public static String payRefundQuery(String WIDbatch_no, String WIDtrade_no) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "refund_fastpay_query");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("batch_no", WIDbatch_no);
				sParaTemp.put("trade_no", WIDtrade_no);
				//建立请求
				return AlipaySubmit.buildRequest("", "", sParaTemp);
			}
			
			/**
			 * 功能说明：支付宝充、退、转账接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午6:05:12
			 * @param WIDbatch_no //批次号 充退转账批次号，只能为11位，且前8位为当前日期（yyyymmdd格式），后3位为字母或数字（商户自定义），必填
			 * @param WIDbatch_num 转账笔数 必填，即参数transfer_data的值中，“|”字符出现的数量加1，最大支持1000笔（即“|”字符出现的数量999个）
			 * @param WIDtransfer_data 转账数据 必填，格式请参考接口技术文档
			 * @return
			 * @throws Exception 
			 */
			public static String payBothFunctionInterface(String WIDbatch_no, String WIDbatch_num, String WIDtransfer_data) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "alipay.trade.refund.transfer.batch");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("batch_no", WIDbatch_no);
				sParaTemp.put("batch_num", WIDbatch_num);
				sParaTemp.put("transfer_data", WIDtransfer_data);
				//建立请求
				return AlipaySubmit.buildRequest("", "", sParaTemp);
			}
			
			/**
			 * 功能说明：支付宝充、退、转账查询接口
			 * 修改说明：
			 * @author 吴兆强
			 * @date 2017年12月28日 下午6:11:44 
			 * @param WIDbatch_no //充退转账批次号 //只能为11位，与交易号不能同时为空
			 * @param WIDtrade_no //支付宝交易号  //该交易在支付宝系统中的交易流水号，与批次号不能同时为空
			 * @return
			 * @throws Exception 
			 */
			public static String payBothFunctionQueryInterface(String WIDbatch_no, String WIDtrade_no) throws Exception {
				//把请求参数打包成数组
				Map<String, String> sParaTemp = new HashMap<String, String>();
				sParaTemp.put("service", "alipay.trade.refund.transfer.batch.query");
		        sParaTemp.put("partner", AlipayConfig.partner);
		        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
				sParaTemp.put("batch_no", WIDbatch_no);
				sParaTemp.put("trade_no", WIDtrade_no);
				//建立请求
				return AlipaySubmit.buildRequest("", "", sParaTemp);
			}
			
}
